package cn.buddha.jesj.lambda.functionInterface.my;

import cn.buddha.jesj.lambda.functionInterface.my.Impl.NoArgumentImpl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName FunctionInterfaceTest
 * @Description Lambda表达式测试类
 * @Author 友野浩二
 * @Version 1.0
 **/
public class FunctionInterfaceTest {

    public static void main(String[] args) {
        // 1- 函数式接口示例
        functionInterfaceExample();

        System.out.println("<<<<======== ========>>>>");

        // 2- forEach示例
        forEachExample();
    }

    /*
     * @Author 友野浩二
     * @Description // forEach示例
     * @Param []
     * @return void
     **/
    private static void forEachExample() {
        // ========== 1- List遍历
        List<String> list = Arrays.asList("java", "c#", "python", "go");

        // before Java8
        System.out.print("before Java8 [");
        for (String str : list) {
            System.out.print(str.concat(" "));
        }
        System.out.print("]" + System.lineSeparator());

        // after Java8
        System.out.println("after Java8 [");
        list.forEach(x -> {
            if ("java".equals(x)) {
                System.out.println("好像是java啊");
            } else {
                System.out.println(x);
            }
        });
        System.out.println("]");

        // ========== 2- Map遍历
        Map<String, String> map = new HashMap<String, String>() {
            private static final long serialVersionUID = 5312419973720583730L;

            {
                put("key1", "value1");
                put("key2", "value2");
                put("key3", "value3");
            }
        };
        map.forEach((k, v) -> System.out.println("key: ".concat(k).concat(", value: ").concat(v)));
    }

    /*
     * @Author 友野浩二
     * @Description // 函数式接口示例
     * @Param []
     * @return void
     **/
    private static void functionInterfaceExample() {
        // ========== 【1- 无参无返回】

        // 1-1 传统方式: 需要new接口的实现类来完成对接口的调用
        INoArgumentInterface nai1 = new NoArgumentImpl();
        nai1.doSomeWork();

        // 1-2 匿名内部类使用
        INoArgumentInterface nai2 = new INoArgumentInterface() {
            @Override
            public void doSomeWork() {
                System.out.println("noArgumentInterface invoked using Anonymous class");
            }
        };
        nai2.doSomeWork();

        // 1-3 无参无返回lambda表达式方式
        INoArgumentInterface nai3 = () -> {
            System.out.println("noArgumentInterface invoked using Lambda expression");
        };
        // ()代表的就是方法，只是匿名的。以为接口只有一个方法，所以可以反推出方法名
        // 类似Java7中的泛型 List<String> list = new ArrayList<>(); Java可以推断出ArrayList的泛型。
        nai3.doSomeWork();

        // 1-4 无参无返回(且只有一行,实现时body体可以去掉{},让lambda表达式更简洁)
        INoArgumentInterface nai4 = () -> System.out.println("noArgumentInterface simpleo invoked using Lambda expression");
        nai4.doSomeWork();

        // ========== 【2- 有参无返回值】
        // 2-1
        IArgumentInterface ai1 = (int a) -> System.out.println("有参无返回值：" + a);
        ai1.argFunction(19);

        // 2-2 参数数据类型和小括号都可以省略
        IArgumentInterface ai2 = a -> System.out.println("有参无返回值,参数数据类型可省略：" + a);
        ai2.argFunction(23);

        // ========== 【3- 多个参数,无返回值】
        IMultipleArgumentInterface mai = (who, content) -> System.out.println(who.concat(" talk ").concat(content));
        mai.multiArgFunction("Shi Hao", "I Love You");

        // ========== 【4- 有返回值】
        IArgumentAndReturnInterface aari1 = (a, b) -> {
            return a * b;
        };
        System.out.println(aari1.calc(2, 3));

        // 4-2 有返回值简写
        // 当lambda表达式只包含一条语句时，可以省略大括号、return和语句结尾的分号
        IArgumentAndReturnInterface aari2 = (a, b) -> a * b;
        System.out.println(aari2.calc(5, 6));

        // ======== 【5- 泛型函数式接口】
        IFuncGeneric<Integer, Integer, Float> funcGeneric = (a, b) -> (5.2f * a * b);
        System.out.println(funcGeneric.getValue(2, 3));
    }

}
